#include "com.hpp"

int main()
{
    // 1.创建公共的key值
    key_t key = ftok(PATH_NAME, PROJ_ID); // ftok的参数为共享内存的路径,并给出一个数字
    if (key < 0)
    {
        perror("ftok error");
        exit(1);
    }
    Log("创建key值成功", DEBUG) << "server key: " << key << endl;

    // 2.创建共享内存 -- 通信的发起者
    int shmid = shmget(key, SHM_SIZE, IPC_CREAT | IPC_EXCL | 0666);
    if (shmid < 0)
    {
        perror("shmget error");
        exit(2);
    }

    // 3.将指定的共享内存,挂接到自己的地址空间
    char *shmaddr = (char *)shmat(shmid, nullptr, 0);
    if (shmaddr == nullptr)
    {
        perror("shmat error");
        exit(3);
    }
    Log("attach shm done", DEBUG) << "shmid: " << shmid << endl;

    // 4.开始通信 ———— 把共享内存当成一个大字符串
    // 共享内存双方通信都是用shm,一方写入数据,另一个立刻就可以看到,但是缺乏访问控制
    int fd = open(FIFO_NAME, O_RDONLY);
    assert(fd != -1);

    while (true)
    {
        Log("等待中 ...", NOTICE) << endl;
        uint32_t tmp = 0;
        ssize_t S = read(fd, &tmp, sizeof(uint32_t));
        assert(S == sizeof(uint32_t));

        // 临界区
        cout << shmaddr << endl;
        if (strcmp(shmaddr, "quit") == 0)
            break;
    }

    // 5.将指定的共享内存, 从自己的地址空间中去关联
    int n1 = shmdt(shmaddr);
    assert(n1 != -1);
    (void)n1;
    Log("detach shm done", DEBUG) << "shmid: " << shmid << endl;

    // 6.删除共享内存,即使有进程和当下的shm链接,依旧删除共享内存
    int n = shmctl(shmid, IPC_RMID, nullptr); // IPC_RMID -> 删除共享内存
    assert(n != -1);
    (void)n;
    Log("delete shm done", DEBUG) << "shmid: " << shmid << endl;

    close(fd);
    return 0;
}